using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Reflection;

using Prota.Unity;
using System;

using MatPropType = Prota.Unity.MaterialPropertyType;

namespace Prota.Editor
{
    [CustomPropertyDrawer(typeof(MaterialPropertyEntry))]
    public class MaterialPropertyEntryPropertyDrawer : PropertyDrawer
    {
        const float lineHeight = 18;
        const float lineSep = 2;
        
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            return lineHeight * 2 + lineSep;
        }
        
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var name = property.FindPropertyRelative("propertyName");
            var type = property.FindPropertyRelative("propertyType");
            var vector = property.FindPropertyRelative("vectorValue");
            var id = Shader.PropertyToID(name.stringValue ?? "");
            var texture = property.FindPropertyRelative("textureValue");
            
            position.height = lineHeight;
            EditorGUI.BeginChangeCheck();
            
            var w = position.size.x;
            
            var sep = position.Shrink(0, w * 0.4f, 0, 0);
            name.stringValue = EditorGUI.TextField(sep, name.stringValue);
            
            sep = position.Shrink(w * 0.6f, w * 0.2f, 0, 0);
            type.enumValueIndex = (int)(MatPropType)EditorGUI.EnumPopup(sep, (MatPropType)type.enumValueIndex);
            
            sep = position.Shrink(w * 0.8f, 0, 0, 0);
            GUI.enabled = false;
            EditorGUI.IntField(sep, id);
            GUI.enabled = true;
            
            position.y += lineHeight + lineSep;
            switch((MatPropType)type.enumValueIndex)
            {
                case MatPropType.Vector4:
                    EditorGUI.Vector4Field(position, name.stringValue, vector.vector4Value);
                    break;
                case MatPropType.Vector3:
                    var newVec3 = EditorGUI.Vector3Field(position, name.stringValue, vector.vector4Value.ToVec3());
                    if(newVec3 != vector.vector4Value.ToVec3()) vector.vector4Value = newVec3.ToVec4();
                    break;
                case MatPropType.Vector2:
                    var newVec2 = EditorGUI.Vector2Field(position, name.stringValue, vector.vector4Value.ToVec2());
                    if(newVec2 != vector.vector4Value.ToVec2()) vector.vector4Value = newVec2.ToVec4();
                    break;
                case MatPropType.Float:
                    var newFloat = EditorGUI.FloatField(position, name.stringValue, vector.vector4Value.x);
                    if(newFloat != vector.vector4Value.x) vector.vector4Value = new Vector4(newFloat, 0, 0, 0);
                    break;
                case MatPropType.Color:
                    var newVec = EditorGUI.ColorField(position, name.stringValue, vector.vector4Value.ToColor()).ToVec4();
                    if(newVec != vector.vector4Value) vector.vector4Value = newVec;
                    break;
                case MatPropType.Texture:
                    EditorGUI.PropertyField(position, texture, new GUIContent(name.stringValue));
                    break;
            }
            
            if(EditorGUI.EndChangeCheck())
            {
                property.serializedObject.ApplyModifiedProperties();
            }
        }
    }
}
